<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>列表拖动排序</title>
    <style>
      ul,
      li {
        list-style: none;
      }
      li {
        width: 200px;
        padding: 10px;
        background-color: red;
        margin-bottom: 10px;
        color: #fff;
      }
      li.moveing {
        background-color: transparent;
        color: transparent;
        border: 1px dashed #ccc;
        border-radius: 10px;
      }
    </style>
  </head>
  <body>
    <ul>
      <li draggable="true">1</li>
      <li draggable="true">2</li>
      <li draggable="true">3</li>
      <li draggable="true">4</li>
      <li draggable="true">5</li>
    </ul>

    <script>
      const ul = document.querySelector('ul');

      let sourceTarget;
      // 开始拖动事件
      ul.ondragstart = (e) => {
        sourceTarget = e.target;
        e.dataTransfer.effectAllowed = 'move'; // 修改鼠标样式
        requestAnimationFrame(() => {
          e.target.classList.add('moveing');
        });
      };

      // 允许放置
      ul.ondragover = (e) => {
        e.preventDefault();
      };

      // 当被拖动的元素进入的时候触发,子元素也包括
      ul.ondragenter = (e) => {
        e.preventDefault();
        if (e.target === ul || e.target === sourceTarget) {
          return;
        }
        const child = Array.from(ul.children);
        // 获取元素在父元素上的索引
        const sourceIndex = child.indexOf(sourceTarget);
        const targetIndex = child.indexOf(e.target);
        if (sourceIndex < targetIndex) {
          console.log('向下');
          ul.insertBefore(sourceTarget, e.target.nextElementSibling);
        } else {
          console.log('向上');
          ul.insertBefore(sourceTarget, e.target);
        }
      };

      // 拖动结束触发
      ul.ondragend = (e) => {
        e.target.classList.remove('moveing');
      };
    </script>
  </body>
</html>
